class_name StatusHandler
extends GridContainer

signal statuses_applied(type: Status.Type)

const STATUS_APPLY_INTERVAL := 0.25
const STATUS_UI_SCENE = preload("uid://cpe52nlfou5wn")

@export var status_owner: Node2D

func apply_status_by_type(type: Status.Type) -> void:
	if type == Status.Type.EVENT_BASED:
		return
	var status_queue := _get_all_status().filter(func(status: Status): return status.type == type)
	if status_queue.is_empty():
		statuses_applied.emit(type)
		return
	var tween := create_tween()
	for status: Status in status_queue:
		tween.tween_callback(status.apply_status.bind(status_owner))
		tween.tween_interval(STATUS_APPLY_INTERVAL)
	tween.finished.connect(func():statuses_applied.emit(type))


func add_status(status: Status) -> void:
	var stackable := status.statck_type != Status.StackType.NONE
	
	if not _has_status(status.id):
		var new_status_ui : StatusUI = STATUS_UI_SCENE.instantiate()
		add_child(new_status_ui)
		new_status_ui.status = status
		new_status_ui.status.status_applied.connect(_on_status_applied)
		new_status_ui.status.initialize_status(status_owner)
		return
	if not status.can_expire and not stackable:
		return
	
	if status.can_expire and status.statck_type == Status.StackType.DURATION:
		_get_status(status.id).duration += status.duration
		return
	
	if status.statck_type == Status.StackType.INTENSITY:
		_get_status(status.id).stacks += status.stacks


func _has_status(id: String) -> bool:
	return get_children().any(func(child: StatusUI): return child.status.id == id)
	
func _get_status(id: String) -> Status:
	for child: StatusUI in get_children():
		if child.status.id == id:
			return child.status
	return null
	
func _get_all_status() -> Array[Status]:
	var statuses: Array[Status] = []
	for child: StatusUI in get_children():
		statuses.append(child.status)
	return statuses
	
func _on_status_applied(status: Status) -> void:
	if status.can_expire:
		status.duration -= 1


func _on_gui_input(event: InputEvent) -> void:
	if event.is_action_pressed("left_mouse"):
		Events.do_status_tooltip_request(_get_all_status())
